home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1998 September / EnigmA AMIGA RUN 30 (1998)(G.R. Edizioni)(IT)[!][issue 1998-09].iso / recent / nc-11u1.lha / nc-1.1 / data / data.c next >
C/C++ Source or Header  |  1998-07-15  |  7KB  |  275 lines

  1. /* primitive arbitrary-data frontend for netcat.  0.9 960226
  2.    only handles one value per ascii line, but at least parses 0xNN too
  3.    an input line containing "%r" during "-g" generates a random byte
  4.  
  5.    todo:
  6.     make work on msloss jus' for kicks [workin' on it...]
  7.  
  8.    syntax: data -X [limit]
  9.    where X is one of
  10.     d: dump raw bytes to ascii format
  11.     g: generate raw bytes from ascii input
  12.     c: generate ??? of value -- NOTYET
  13.     r: generate all random bytes
  14.    and limit is how many bytes to generate or dump [unspecified = infinite]
  15.  
  16.    *Hobbit*, started 951004 or so and randomly screwed around with since */
  17.  
  18. #include <stdio.h>
  19.  
  20. #ifdef MSDOS                /* for MSC only at the moment... */
  21. #include <fcntl.h>
  22. #else /* MSDOS */
  23. #include <sys/file.h>
  24. #define HAVE_RANDOM            /* XXX: might have to change */
  25. #endif /* MSDOS */
  26.  
  27. static char buf_in [128];
  28. static char buf_raw [8192];
  29. static char surveysez[] = "survey sez... XXX\n";
  30.  
  31. /* fgetss :
  32.    wrapper for fgets, that yanks trailing newlines.  Doing the work ourselves
  33.    instead of calling strchr/strlen/whatever */
  34. char * fgetss (buf, len, from)
  35.   char * buf;
  36.   size_t len;
  37.   FILE * from;
  38. {
  39.   register int x;
  40.   register char * p, * q;
  41.   p = fgets (buf, len, from);        /* returns ptr to buf */
  42.   if (! p)
  43.     return (NULL);
  44.   q = p;
  45.   for (x = 0; x < len; x++) {
  46.     *p = (*p & 0x7f);            /* rip parity, just in case */
  47.     switch (*p) {
  48.       case '\n':
  49.       case '\r':
  50.       case '\0':
  51.     *p = '\0';
  52.     return (q);
  53.     } /* switch */
  54.     p++;
  55.   } /* for */
  56. } /* fgetss */
  57.  
  58. /* randint:
  59.    swiped from rndb.c.  Generates an INT, you have to mask down to char. */
  60. int randint()
  61. {
  62.   register int q;
  63.   register int x;
  64.  
  65. #ifndef HAVE_RANDOM
  66.   q = rand();
  67. #else
  68.   q = random();
  69. #endif
  70.   x = ((q >> 8) & 0xff);    /* perturb low byte using some higher bits */
  71.   x = q ^ x;
  72.   return (x);
  73. }
  74.  
  75. main (argc, argv)
  76.   int argc;
  77.   char ** argv;
  78. {
  79.   register unsigned char * p;
  80.   register char * q;
  81.   register int x;
  82.   int bc = 0;
  83.   int limit = 0;        /* num to gen, or 0 = infinite */
  84.   register int xlimit;        /* running limit */
  85.   FILE * txt;            /* line-by-line ascii file */
  86.   int raw;            /* raw bytes fd */
  87.   int dumping = 0;        /* cmd flags ... */
  88.   int genning = 0;
  89.   int randing = 0;
  90.  
  91.   memset (buf_in, 0, sizeof (buf_in));
  92.   memset (buf_raw, 0, sizeof (buf_raw));
  93.  
  94.   xlimit = 1;                /* doubles as "exit flag" */
  95.   bc = 1;                /* preload, assuming "dump" */
  96.   x = getpid() + 687319;
  97. /* if your library doesnt have srandom/random, use srand/rand. [from rnd.c] */
  98. #ifndef HAVE_RANDOM
  99.   srand (time(0) + x);
  100. #else
  101.   srandom (time(0) + x);
  102. #endif
  103.  
  104. #ifdef O_BINARY
  105. /* DOS stupidity */
  106. /* Aha: *here's* where that setmode() lib call conflict in ?BSD came from */
  107.   x = setmode (0, O_BINARY);        /* make stdin raw */
  108.   if (x < 0) {
  109.     fprintf (stderr, "stdin binary setmode oops: %d\n", x);
  110.     exit (1);
  111.   }
  112.   x = setmode (1, O_BINARY);        /* make stdout raw */
  113.   if (x < 0) {
  114.     fprintf (stderr, "stdout binary setmode oops: %d\n", x);
  115.     exit (1);
  116.   }
  117. #endif /* O_BINARY */
  118.  
  119.   if (argv[1]) {
  120.     p = argv[1];        /* shit-simple single arg parser... */
  121.     if (*p == '-')        /* dash is optional, we'll deal */
  122.       p++;
  123.     if (*p == 'd')
  124.       dumping++;
  125.     if (*p == 'g')
  126.       genning++;
  127.     if (*p == 'r')
  128.       randing++;
  129.   } /* if argv 1 */
  130.  
  131. /* optional second argument: limit # of bytes shoveled either way */
  132.   if (argv[2]) {
  133.     x = atoi (argv[2]);
  134.     if (x)
  135.       limit = x;
  136.     else
  137.       goto wrong;
  138.     xlimit = limit;
  139.   }
  140.  
  141. /* Since this prog would likely best be written in assmbler, I'm gonna
  142.    write it *like* assembler.  So there. */
  143.  
  144.   if (randing)
  145.     goto do_rand;
  146.  
  147. nextbuf:                /* loop sleaze */
  148.  
  149.   if (dumping) {            /* switch off to wherever */
  150.     if (genning)
  151.       goto wrong;
  152.     goto do_dump;
  153.   }
  154.   if (genning)
  155.     goto do_gen;
  156. wrong:
  157.   fprintf (stderr, surveysez);        /* if both or neither */
  158.   exit (1);
  159.  
  160. do_gen:
  161. /* here if genning -- original functionality */
  162.   q = buf_raw;
  163.   bc = 0;
  164. /* suck up lines until eof or buf_raw is full */
  165.   while (1) {
  166.     p = fgetss (buf_in, 120, stdin);
  167.     if (! p)
  168.       break;                /* EOF */
  169. /* super-primitive version first: one thingie per line */
  170.     if (*p == '#')            /* comment */
  171.       continue;
  172.     if (*p == '\0')            /* blank line */
  173.       continue;
  174.     if (*p == '%') {            /* escape char? */
  175.       p++;
  176.       if (*p == 'r') {            /* random byte */
  177.     x = randint();
  178.     goto stuff;
  179.       } /* %r */
  180.     } /* if "%" escape */
  181.     if (*p == '0')
  182.       if (*(p+1) == 'x')        /* 0x?? */
  183.     goto hex;
  184.     x = atoi (p);            /* reg'lar decimal number */
  185.     goto stuff;
  186.  
  187. hex:
  188. /* A 65   a 97 */
  189. /* xxx: use a conversion table for this or something.  Since we ripped the
  190.    parity bit, we only need a preset array of 128 with downconversion factors
  191.    loaded in *once*.   maybe look at scanf... */
  192.     p++; p++;                /* point at hex-chars */
  193.     x = 0;
  194.     if ((*p > 96) && (*p < 123))    /* a-z */
  195.       *p = (*p - 32);            /* this is massively clumsy */
  196.     if ((*p > 64) && (*p < 71))        /* A-F */
  197.       x = (*p - 55);
  198.     if ((*p > 47) && (*p < 58))        /* digits */
  199.       x = (*p - 48);
  200.     p++;
  201.     if (*p)                /* another digit? */
  202.       x = (x << 4);            /* shift to hi half */
  203.     if ((*p > 96) && (*p < 123))    /* a-z */
  204.       *p = (*p - 32);
  205.     if ((*p > 64) && (*p < 71))        /* A-F */
  206.       x = (x | (*p - 55));        /* lo half */
  207.     if ((*p > 47) && (*p < 58))        /* digits */
  208.       x = (x | (*p - 48));
  209.  
  210. /* fall thru */
  211. stuff:                    /* cvt to byte and add to buffer */
  212.     *q = (x & 0xff);
  213.     q++;
  214.     bc++;
  215.     if (limit) {
  216.       xlimit--;
  217.       if (xlimit == 0)            /* max num reached */
  218.     break;
  219.     } /* limit */
  220.     if (bc >= sizeof (buf_raw))        /* buffer full */
  221.       break;
  222.   } /* while 1 */
  223.  
  224. /* now in theory we have our buffer formed; shovel it out */
  225.   x = write (1, buf_raw, bc);
  226.   if (x <= 0) {
  227.     fprintf (stderr, "write oops: %d\n", x);
  228.     exit (1);
  229.   }
  230.   if (xlimit && p)
  231.     goto nextbuf;            /* go get some more */
  232.   exit (0);
  233.  
  234. do_dump:
  235. /* here if dumping raw stuff into an ascii file */
  236. /* gad, this is *so* much simpler!  can we say "don't rewrite printf"? */
  237.   x = read (0, buf_raw, 8192);
  238.   if (x <= 0)
  239.     exit (0);
  240.   q = buf_raw;
  241.   for ( ; x > 0; x--) {
  242.     p = q;
  243.     printf ("%-3.3d # 0x%-2.2x # ", *p, *p);
  244.     if ((*p > 31) && (*p < 127))
  245.       printf ("%c %d\n", *p, bc);
  246.     else
  247.       printf (". %d\n", bc);
  248.     q++;
  249.     bc++;
  250.     if (limit) {
  251.       xlimit--;
  252.       if (xlimit == 0) {
  253.     fflush (stdout);
  254.     exit (0);
  255.       }
  256.     } /* limit */
  257.   } /* for */
  258.   goto nextbuf;
  259.  
  260. do_rand:
  261. /* here if generating all-random bytes.  Stays in this loop */
  262.   p = buf_raw;
  263.   while (1) {
  264.     *p = (randint() & 0xff);
  265.     write (1, p, 1);            /* makes very slow! */
  266.     if (limit) {
  267.       xlimit--;
  268.       if (xlimit == 0)
  269.     break;
  270.     }
  271.   } /* while */
  272.   exit (0);
  273.  
  274. } /* main */
  275.